package com.zhoug.viewpermission;

import static com.zhoug.viewpermission.NavigationMenu.STATUS_NORMAL;

import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * @author: zhoug
 * @since: 2025-06-12
 */
public class MenuRepository {
    private final List<Disposable> mListDisposable = new ArrayList<>();

    public MenuRepository() {

    }

    private MenuDao getMenuDao() {
        return MenuDatabase.getInstance().getPageMenuDao();
    }

    public MenuRepository(@Nullable LifecycleOwner lifecycleOwner) {
        this();
        setLifecycleOwner(lifecycleOwner);
    }


    public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
        if (lifecycleOwner != null) {
            lifecycleOwner.getLifecycle().addObserver(new DefaultLifecycleObserver() {
                @Override
                public void onDestroy(@NonNull LifecycleOwner owner) {
                    unDisposable();
                }
            });
        }
    }

    /**
     * 根据path查询菜单
     *
     * @param path
     * @param callback
     */
    public void getMenuByPath(String path, @NonNull Callback<NavigationMenu> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<NavigationMenu>>) emitter -> {
                    NavigationMenu menu = MenuDaoHelper.getMenuByPath(path);
                    emitter.onNext(Optional.create(menu));
                    emitter.onComplete();

                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }


    /**
     * 根据上级菜单id查询子菜单
     *
     * @param id
     * @param callback
     */
    public void getChildrenByParentId(String id, @NonNull Callback<List<NavigationMenu>> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                    List<NavigationMenu> children = MenuDaoHelper.getChildrenByParentId(id);
                    emitter.onNext(Optional.create(children));
                    emitter.onComplete();

                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }

    /**
     * 根据上级菜单id单递归查询所有子菜单
     *
     * @param id
     * @param callback
     */
    public void getAllChildrenByParentId(String id, @NonNull Callback<List<NavigationMenu>> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                    List<NavigationMenu> children = MenuDaoHelper.getAllChildrenByParentId(id);
                    emitter.onNext(Optional.create(children));
                    emitter.onComplete();

                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }

    /**
     * 根据上级菜单id单递归查询所有子菜单
     *
     * @param id
     * @param callback
     */
    public void getChildrenByParentId(String id, int level, @NonNull Callback<List<NavigationMenu>> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                    List<NavigationMenu> children = MenuDaoHelper.getChildrenByParentId(id, level);
                    emitter.onNext(Optional.create(children));
                    emitter.onComplete();

                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }


    /**
     * 根据上级菜单path查询子菜单
     *
     * @param path
     * @param callback
     */
    public void getChildrenByParentPath(String path, @NonNull Callback<List<NavigationMenu>> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                    List<NavigationMenu> children = MenuDaoHelper.getChildrenByParentPath(path);
                    emitter.onNext(Optional.create(children));
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }


    /**
     * 根据上级菜单path递归查询所有子菜单
     *
     * @param path
     * @param callback
     */
    public void getAllChildrenByParentPath(String path, @NonNull Callback<List<NavigationMenu>> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                    List<NavigationMenu> children = MenuDaoHelper.getAllChildrenByParentPath(path);
                    emitter.onNext(Optional.create(children));
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }


    /**
     * 根据上级菜单path递归查询所有子菜单
     *
     * @param path
     * @param callback
     */
    public void getChildrenByParentPath(String path, int level, @NonNull Callback<List<NavigationMenu>> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<List<NavigationMenu>>>) emitter -> {
                    List<NavigationMenu> children = MenuDaoHelper.getChildrenByParentPath(path, level);
                    emitter.onNext(Optional.create(children));
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);
    }


    public void getPermissionInKeys(List<String> keys, @NonNull Callback<List<ViewPermission>> callback) {
        if (keys == null || keys.isEmpty()) {
            callback.onSuccess(null);
        } else {
            Disposable disposable = Observable
                    .create((ObservableOnSubscribe<Optional<List<ViewPermission>>>) emitter -> {
                        List<ViewPermission> permissions = MenuDaoHelper.getPermissionsByKeys(keys);
                        emitter.onNext(Optional.create(permissions));
                        emitter.onComplete();
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                        throwable.printStackTrace();
                        callback.onFailure(throwable.getMessage());
                    });
            addDisposable(disposable);
        }
    }

    /**
     * 获取摄像头操作权限
     *
     * @param permission 权限字符串,为null时默认为:{@link MonitorControlPermissions#PERMISSION_KEY_MONITOR}
     * @param callback
     */
    public void getMonitorControlPermissions(@Nullable String permission, @NonNull Callback<MonitorControlPermissions> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<MonitorControlPermissions>>) emitter -> {
                    List<NavigationMenu> menus = MenuDaoHelper.getPermissionsByKey(TextUtils.isEmpty(permission) ? MonitorControlPermissions.PERMISSION_KEY_MONITOR : permission);
                    MonitorControlPermissions result=new MonitorControlPermissions();
                    if(menus!=null && !menus.isEmpty()){
                        for (NavigationMenu item : menus) {
                            String permissionKey = item.getPermissionKey();
                            if (!TextUtils.isEmpty(permissionKey)) {
                                permissionKey = permissionKey.trim();
                            }
                            int status = item.getStatus();
                            if (!TextUtils.isEmpty(permissionKey)) {
                                if (permissionKey.equalsIgnoreCase(MonitorControlPermissions.RECORD_VIDEO)) {
                                    result.setRecordVideoEnable(status == STATUS_NORMAL);
                                } else if (permissionKey.equalsIgnoreCase(MonitorControlPermissions.CAPTURE_IMAGE)) {
                                    result.setCaptureImageEnable(status == STATUS_NORMAL);
                                } else if (permissionKey.equalsIgnoreCase(MonitorControlPermissions.TALK)) {
                                    result.setTalkEnable(status == STATUS_NORMAL);
                                } else if (permissionKey.equalsIgnoreCase(MonitorControlPermissions.INSPECT)) {
                                    result.setInspectEnable(status == STATUS_NORMAL);
                                } else if (permissionKey.equalsIgnoreCase(MonitorControlPermissions.PLAYBACK)) {
                                    result.setPlaybackEnable(status == STATUS_NORMAL);
                                } else if (permissionKey.equalsIgnoreCase(MonitorControlPermissions.MUTE)) {
                                    result.setMuteEnable(status == STATUS_NORMAL);
                                }
                            }
                        }

                    }
                    emitter.onNext(Optional.create(result));
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(opt -> callback.onSuccess(opt.get()), throwable -> {
                    throwable.printStackTrace();
                    callback.onFailure(throwable.getMessage());
                });
        addDisposable(disposable);

    }

    public static void bindPermission(ViewPermission permission, List<NavigationMenu> menus) {
        if (menus != null && !menus.isEmpty()) {
            for (NavigationMenu item : menus) {
                String permissionKey = item.getPermissionKey();
                if (!TextUtils.isEmpty(permissionKey)) {
                    permissionKey = permissionKey.trim().toLowerCase();
                }
                if (!TextUtils.isEmpty(permissionKey)) {
                    permission.setPermissionText(permissionKey);
                    switch (permissionKey) {
                        case ViewPermission.ADD -> permission.setAddPermission(true);
                        case ViewPermission.UPDATE -> permission.setUpdatePermission(true);
                        case ViewPermission.DELETE -> permission.setDeletePermission(true);
                        case ViewPermission.AUDIT -> permission.setAuditPermission(true);
                        case ViewPermission.IMPORT -> permission.setImportPermission(true);
                        case ViewPermission.EXPORT -> permission.setExportPermission(true);
                    }
                }
            }
        }
    }


    public void addDisposable(Disposable disposable) {
        if (disposable != null) {
            mListDisposable.add(disposable);
        }
    }

    public void removeDisposable(Disposable disposable) {
        try {
            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void unDisposable() {
        for (Disposable disposable : mListDisposable) {
            removeDisposable(disposable);
        }
        mListDisposable.clear();
    }


}
